IAM アクションの一覧を取得する方法を教えてください

IAM アクションの一覧を取得する方法を教えてください

Clock Icon2024.12.22

この記事は アノテーション株式会社 AWS Technical Support Advent Calendar 2024 | Advent Calendar 2024 - Qiita 22日目の記事です。

困っていること

IAM アクションの一覧をプログラムで取得する方法を探しています。 AWS SDK 等で API を探しましたが、該当する機能の API は見つかりませんでした。

どう対応すればいいの?

IAM のアクション一覧を取得するような API は AWS から提供されていません。
そのため、お客様ご自身で IAM アクションの一覧を取得するプログラムを実装いただく必要があります。

具体的な実装方法としてはお客様の実行環境や要件等によって異なるとは存じますが、一例として Lambda (Node.js) で IAM アクションの一覧を返す関数を作成する例をご紹介します。

IAM アクション一覧を取得する Lambda 関数の例

例として、 AWS 公式ドキュメントの Amazon S3 のアクション一覧 から IAM アクション一覧を取得する例を考えます。
今回は実行環境として Node.js v22を選択し、 HTML パーサーには node-html-parserを、 HTTP 通信には node-fetch を利用します。

import { parse } from 'node-html-parser';
import fetch from 'node-fetch';

export const handler = async (event) => {
  const url = new URL(event.queryStringParameters.url);
  if (url.hostname !== 'docs.aws.amazon.com') {
    return { statusCode: 400 };
  }
  const actions = await getActions(url);
  const response = {
    statusCode: 200,
    body: JSON.stringify({ actions: actions }),
  };
  return response;
};

async function getActions(url) {
  // HTML を取得
  const response = await fetch(url);
  const body = await response.text();

  // HTML をパース
  const $html = parse(body);
  const $table  = $html.querySelector('[id*=-actions-as-permissions] ~ div.table-container table')
  const columns = $table.querySelectorAll('thead tr th').length;

  // テーブルからアクション名を抽出
  const actions = $table.querySelectorAll('tr').filter(($action, index) => {
    // 必要な行のみ抽出
    if (index === 0) {
      // 見出し行はスキップ
      return false;
    } else if ($action.querySelectorAll('td').length < columns) {
      // 結合された行はスキップ
      return false;
    } else {
      return true;
    }
  }).map($action => {
    // リンクからアクション名を抽出
    const actionName = $action.querySelector('a').textContent;
    return actionName;
  });

  return actions;
}

中身について詳しく解説します。

公式ドキュメントの構造を見ると、 Amazon S3 で定義されるアクション という h2 見出しの直下に、取得したい IAM アクション一覧が含まれる table テーブルがあります。見出しには -actions-as-permissions で終わる ID がついており、テーブルはその兄弟要素として div.table-container の孫要素あたりにいるので、セレクターとしてまとめるとテーブルの要素は [id*=-actions-as-permissions] ~ div.table-container table で表現できます。

あとはテーブルの中を行ごとに見てアクション名を取得すれば良いですが、行によっては rowspan で結合されているため単純に行ごとに見ると不要な要素も取得されます。列の数が欠けている行を結合された不要な行としてみなして、必要な行のみを取得することで、必要なアクション名を取得することができます。

あとは、IAM や EC2 等、他のアクションについても公式ドキュメントの構造はほとんど同じなので、汎用的に API として利用できるよう、 API Gateway から url パラメータで公式ドキュメントの URL を受け取り、アクション名を取得して返すようにしています。

注意点

AWS 公式ドキュメントの構造は予告なく変更される場合がありますので、永続的に利用できる解決策ではないことをご留意ください。
あくまで上記に添付のコードはサンプルコードとなりますので参考程度にご利用いただくものとし、本番環境で利用される場合には、お客様ご自身で事前に十分に検証を行っていただくようお願い申し上げます。

参考資料

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.